#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#include <stdlib.h>
#define BUF_SIZE 64

void handler(int sig){
    wait(NULL);
    return;
}

int main(void){
    int sockfd = socket(AF_INET,SOCK_STREAM,0);//ipv4,tcp
    if(sockfd == -1){
        perror("sock err");
        return -1;
    }
    //服务器地址:IP 端口号
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port =htons(8080);
    
    addr.sin_addr.s_addr=INADDR_ANY;//本地的ip都可以
    printf("IP=%s\n",inet_ntoa(addr.sin_addr));
    socklen_t addrlen= sizeof(addr);
    //绑定
    if(bind(sockfd,(struct sockaddr*)&addr,addrlen) == -1){
        perror("bind err");
        close(sockfd);
        return -1;
    }

    //监听
    if(listen(sockfd,10) == -1){
        perror("listen err");
        close(sockfd);
        return -1;
    }
    printf("waiting client connect!\n");

    //响应连接
    struct sockaddr_in client_addr;
    socklen_t clientlen;

    int clientfd =0;
    
    //收发数据
    signal(SIGCHLD,handler);

  
    char name[BUF_SIZE]={};
    pid_t pid=-1;
    while(1){
        clientfd=accept(sockfd,(struct sockaddr *)&client_addr,&clientlen);
        if(clientfd < 0){
            perror("accept err");
            close(sockfd);
            return -1;
        }
        printf("sockfd=%d clientfd=%d\n",sockfd,clientfd);
        printf("new connect comming\n");

        pid = fork();
        if(pid < 0){
            perror("fork err");
            return -1;
        }else if(pid == 0){
             int ret;
            char buf[BUF_SIZE] = {0};
            while (1)
            {
                ret = recv(clientfd, buf, BUF_SIZE, 0);
                if (ret < 0)
                {
                    perror("recv err");
                    continue;
                }
                else if (ret == 0)
                {
                    printf("peer exit\n");
                    break;
                }
                else
                {
                    printf("ip = %s, port = %d, data = %s\n",
                    inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), buf);
                }
            }
            close(clientfd);
            // close();
            exit(0);
        }else{
            close(clientfd);
        }
    }

    wait(NULL);
    //关闭
    close(sockfd);

    return 0;
}
